package com.dragon.modules.yuegou.service.impl.merchant;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dragon.common.exception.DragonException;
import com.dragon.modules.yuegou.entity.merchant.MerchantEntity;
import com.dragon.modules.yuegou.entity.merchant.MerchantLevelEntity;
import com.dragon.modules.yuegou.entity.merchant.MerchantLevelRuleDetailEntity;
import com.dragon.modules.yuegou.enums.code.MerchantCode;
import com.dragon.modules.yuegou.enums.merchant.MerchantLevelOrderType;
import com.dragon.modules.yuegou.enums.merchant.MerchantLevelStatus;
import com.dragon.modules.yuegou.enums.order.OrderType;
import com.dragon.modules.yuegou.mapper.merchant.MerchantLevelRuleDetailMapper;
import com.dragon.modules.yuegou.model.merchant.Merchant;
import com.dragon.modules.yuegou.model.merchant.MerchantLevel;
import com.dragon.modules.yuegou.model.merchant.MerchantLevelRule;
import com.dragon.modules.yuegou.model.order.Order;
import com.dragon.modules.yuegou.query.merchant.MerchantLevelQuery;
import com.dragon.modules.yuegou.service.merchant.MerchantLevelRuleDetailService;
import com.dragon.modules.yuegou.service.merchant.MerchantLevelRuleService;
import com.dragon.modules.yuegou.service.merchant.MerchantLevelService;
import com.dragon.modules.yuegou.service.merchant.MerchantService;
import com.dragon.modules.yuegou.service.order.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 等级规则-明细 服务实现
 *
 * @author pbuilder generated
 * @date 2019-09-23 15:29:07
 * @version 2.0
 */
@Slf4j
@Service("merMerchantLevelRuleDetailService")
public class MerchantLevelRuleDetailServiceImpl extends
		ServiceImpl<MerchantLevelRuleDetailMapper, MerchantLevelRuleDetailEntity>
		implements MerchantLevelRuleDetailService {

	@Autowired
	private MerchantLevelRuleService merchantLevelRuleService;

	@Autowired
	private MerchantLevelService merchantLevelService;

	@Autowired
	private MerchantService merchantService;

	@Autowired
	private OrderService orderService;

	@Override
	public void payCallBack(String orderNo) {

		Order order = orderService.getOrder(orderNo);

		MerchantLevelQuery merchantLevelQuery = new MerchantLevelQuery();
		merchantLevelQuery.orderNo().eq(orderNo);

		MerchantLevelEntity one = merchantLevelService.getOne(merchantLevelQuery.toQueryWrapper());
		if (null != one) {
			// 修改已存在的商户等级为无效
			MerchantLevelQuery levelQuery = new MerchantLevelQuery();
			levelQuery.merchantId().eq(one.getMerchantId());
			levelQuery.status().eq(MerchantLevelStatus.PAID);
			List<MerchantLevelEntity> list = merchantLevelService.list(levelQuery.toQueryWrapper());
			if (CollectionUtils.isNotEmpty(list)) {
				for (MerchantLevelEntity level : list) {
					level.setStatus(MerchantLevelStatus.INVALID);
				}
				merchantLevelService.updateBatchById(list);
			}
			// 本条记录生效
			LocalDateTime now = LocalDateTime.now();
			one.setStatus(MerchantLevelStatus.PAID);
			one.setPayAmount(order.getPayAmount());
			one.setBuyTime(now);
			one.setModifiedTime(now);
			merchantLevelService.updateById(one);
		}
	}

	@Override
	@Transactional
	public Order order(String detailId, String merchantId) {

		MerchantLevelRuleDetailEntity merchantLevelRuleDetail = getById(detailId);
		MerchantLevelRule merchantLevelRule = merchantLevelRuleService.getLevelRule(merchantLevelRuleDetail.getLevelRuleId());
		MerchantEntity merchant = merchantService.getById(merchantId);

		MerchantLevel merchantLevel = addMerchantLevel(merchantLevelRule, merchantLevelRuleDetail, merchant);
		LocalDateTime now = LocalDateTime.now();

		// *****************************************
		// 1、本次等级原价
		// 判断折扣期限是否过期，如果过期，则取原价购买
		BigDecimal needPayAmount = getNeedPayAmount(merchantId,now, merchantLevel, merchantLevelRuleDetail, merchantLevelRule);

		// *****************************************
		Order request = new Order();
		request.setMerchantBuyer(new Merchant(merchant));
		request.setType(OrderType.MERCHANT_LEVEL_BUY);
		request.setBusdId(merchant.getBusdId());
		request.setAmount(needPayAmount);
		request.setPoints(0);
		request.setMerchantId(merchant.getId());
		Order order = orderService.placeOrder(request);

		if (null != order) {
			merchantLevel.setOrderNo(order.getId());
			merchantLevel.setOrderTime(now);
			merchantLevelService.updateById(merchantLevel);
		}

		return order;
	}

	private BigDecimal getNeedPayAmount(String merchantId,LocalDateTime now, MerchantLevel merchantLevel,
			MerchantLevelRuleDetailEntity merchantLevelRuleDetail, MerchantLevelRule merchantLevelRule) {
		BigDecimal discountPrice = merchantLevelRuleDetail.getDiscountPrice();
		if (now.isAfter(merchantLevelRuleDetail.getEndTime())
				|| now.isBefore(merchantLevelRuleDetail.getStartTime())) {
			discountPrice = merchantLevelRuleDetail.getUnitPrice();
		}

		BigDecimal needPayAmount = null;
		// 2、查询该商铺所属等级 （到期日-本日）*（旗舰每日价格-高级每日价格）+剩余天数*旗舰会员价格
		MerchantLevel currMerchantLevel = getMerchantLevel(merchantId);
		if (null != currMerchantLevel) {
			needPayAmount = hasMerchantLevel(currMerchantLevel,merchantLevel,discountPrice,merchantLevelRuleDetail,merchantLevelRule);
		} else {
			merchantLevel.setOrderType(MerchantLevelOrderType.BUY);// 从未购买过，或已过期的再购买的，都定义为：全新购买
			needPayAmount = discountPrice;// 需支付金额
			merchantLevel.setStartTime(now);
			merchantLevel.setEndTime(now.plusMonths(merchantLevelRuleDetail.getPeriodValidity()));
		}
		return needPayAmount;
	}

	private BigDecimal hasMerchantLevel(MerchantLevel currMerchantLevel,MerchantLevel merchantLevel,BigDecimal discountPrice,
										MerchantLevelRuleDetailEntity merchantLevelRuleDetail,MerchantLevelRule merchantLevelRule){
		BigDecimal needPayAmount = discountPrice;
		// 存在有效的等级，判断是续费，还是升级
		if (merchantLevel.getLevelId().equals(currMerchantLevel.getLevelId())) {// ID相同，续费
			needPayAmount = discountPrice;// 需支付金额
			merchantLevel.setOrderType(MerchantLevelOrderType.RENEWAL);
			// 续费注意：同等级续费，则续费的时间，在原来续费的结束时间上增加月份/天数
			merchantLevel.setStartTime(merchantLevel.getStartTime());
			merchantLevel
					.setEndTime(merchantLevel.getEndTime().plusMonths(merchantLevelRuleDetail.getPeriodValidity()));
		} else {// 升级
			if (merchantLevelRule.getLevelName().indexOf("高级") > -1) {
				log.error("旗舰商家不能降级购买高级商家产品");
				throw new DragonException(MerchantCode.LEVEL_ERROR);
			}
			merchantLevel.setOrderType(MerchantLevelOrderType.UPLEVEL);
			long days = Duration.between(currMerchantLevel.getStartTime(), currMerchantLevel.getEndTime())
					.toDays();
			// 平均每天的价格
			BigDecimal payAmount = currMerchantLevel.getPayAmount();
			BigDecimal avgDayofAmout = payAmount.divide(new BigDecimal(days),2, BigDecimal.ROUND_HALF_UP);
			// 计算历史等级有效期剩余天数
			long remainDays = Duration.between(LocalDateTime.now(), currMerchantLevel.getEndTime()).toDays();
			// 通过此次购买的等级需要支付的金额 = 旗舰所需支付金额 - （高级会员支付金额/高级会员天数*高级会员剩余天数）
			BigDecimal balanceSubtract = discountPrice.subtract(avgDayofAmout.multiply(new BigDecimal(remainDays)));
			if (balanceSubtract.compareTo(discountPrice)>0) {
				balanceSubtract = discountPrice;
			}
			if (balanceSubtract.compareTo(BigDecimal.ZERO) > 0) {
				// 需要支付，否则无需支付
				needPayAmount = balanceSubtract;// 需支付金额
				merchantLevel.setUpgradeAmount(discountPrice.subtract(needPayAmount));// 升级抵扣金额
			}
		}
		return needPayAmount;
	}

	private MerchantLevel addMerchantLevel(MerchantLevelRule merchantLevelRule,
										   MerchantLevelRuleDetailEntity merchantLevelRuleDetail, MerchantEntity merchant) {
		LocalDateTime now = LocalDateTime.now();
		MerchantLevel level = new MerchantLevel();
		level.setMerchantId(merchant.getId());
		level.setMerchantName(merchant.getMerchantName());
		level.setLevelId(merchantLevelRule.getId());
		level.setStatus(MerchantLevelStatus.NOPAY);
		level.setBuyTime(now);
		level.setPeriodValidity(merchantLevelRuleDetail.getPeriodValidity());
		level.setOrderTime(now);

		level.setLevelDetailId(merchantLevelRuleDetail.getId());
		level.setStartTime(now);
		level.setEndTime(now.plusMonths(merchantLevelRuleDetail.getPeriodValidity()));
		merchantLevelService.save(level);

		return level;
	}

	private MerchantLevel getMerchantLevel(String merchantId) {
		MerchantLevelQuery levelQuery = new MerchantLevelQuery();
		levelQuery.merchantId().eq(merchantId);
		levelQuery.status().eq(MerchantLevelStatus.PAID);
		List<MerchantLevelEntity> list = merchantLevelService.list(levelQuery.toQueryWrapper());

		MerchantLevel merchantLevel = null;
		if (CollectionUtils.isNotEmpty(list)) {
			merchantLevel = new MerchantLevel(list.get(0));
		}
		return merchantLevel;
	}

	@Override
	public BigDecimal getPayByDetailId(String merchantId,String detailId) {

		MerchantLevelRuleDetailEntity merchantLevelRuleDetail = getById(detailId);
		MerchantLevelRule merchantLevelRule = merchantLevelRuleService.getLevelRule(merchantLevelRuleDetail.getLevelRuleId());
		MerchantLevel merchantLevel = getMerchantLevel(merchantId);

		return getPayPrice(merchantLevelRuleDetail, merchantLevel, merchantLevelRule);
	}

	private BigDecimal getPayPrice(MerchantLevelRuleDetailEntity merchantLevelRuleDetail, MerchantLevel merchantLevel,
			MerchantLevelRule merchantLevelRule) {
		BigDecimal discountPrice = merchantLevelRuleDetail.getDiscountPrice();
		LocalDateTime now = LocalDateTime.now();
		if (now.isAfter(merchantLevelRuleDetail.getEndTime()) || now.isBefore(merchantLevelRuleDetail.getStartTime())) {
			discountPrice = merchantLevelRuleDetail.getUnitPrice();
		}

		BigDecimal balanceSubtract = discountPrice;
		if (null != merchantLevel) {
			// 存在有效的等级，判断是续费，还是升级
			if (merchantLevel.getLevelId().equals(merchantLevelRuleDetail.getLevelRuleId())) {// ID相同，续费
				balanceSubtract = discountPrice;
			} else {// 升级
				if (merchantLevelRule.getLevelName().indexOf("高级") > -1) {
					return new BigDecimal(-1);
				}
				long days = Duration.between(merchantLevel.getStartTime(), merchantLevel.getEndTime()).toDays();
				// 平均每天的价格
				BigDecimal payAmount = merchantLevel.getPayAmount();
				BigDecimal avgDayofAmout = payAmount.divide(new BigDecimal(days),2, BigDecimal.ROUND_HALF_UP) ;
				// 计算历史等级有效期剩余天数
				long remainDays = Duration.between(now, merchantLevel.getEndTime()).toDays();
				// 通过此次购买的等级需要支付的金额 = 旗舰所需支付金额 - （高级会员支付金额/高级会员天数*高级会员剩余天数）
				balanceSubtract =discountPrice.subtract(avgDayofAmout.multiply(new BigDecimal(remainDays)));
			}
		}
		balanceSubtract = balanceSubtract.setScale(2, BigDecimal.ROUND_HALF_UP);
		return balanceSubtract;
	}
}